package com.cobo.common.core;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.apache.hc.client5.http.classic.methods.HttpGet;
import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
import org.apache.hc.client5.http.impl.classic.CloseableHttpResponse;
import org.apache.hc.client5.http.impl.classic.HttpClients;
import org.apache.hc.core5.http.io.entity.EntityUtils;
import org.apache.hc.core5.net.URIBuilder;
import org.apache.hc.core5.ssl.SSLContextBuilder;
import org.apache.hc.core5.ssl.SSLContexts;
import org.apache.hc.core5.ssl.TrustStrategy;

import javax.net.ssl.SSLContext;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.HashMap;
import java.util.Map;

@Slf4j
public class Requests {

    public static final int HTTP_OK = 200;
    private static CloseableHttpClient createHttpClientWithNoSsl() throws Exception {
        // Create a trust manager that does not validate certificate chains
        SSLContext sslContext = null;
        try {
            SSLContextBuilder custom = SSLContexts.custom();
            custom.loadTrustMaterial(null, new TrustStrategy() {
                @Override
                public boolean isTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {
                    return true;
                }
            });
            sslContext = custom.build();
        } catch (Exception e) {
            log.error("HttpUtils class createHttpClientWithNoSsl method execute exception", e);
        }

//                LayeredConnectionSocketFactory sslSocketFactory = new SSLConnectionSocketFactory(ctx);
        return HttpClients.custom()
//                .setSSLContext(sslContext)
//                .setSSLHostnameVerifier(new NoopHostnameVerifier())
                .build();
    }

    public static void download(String url, Map<String, String> params, Map<String, String> headers, File file) {
        CloseableHttpResponse res = null;
        CloseableHttpClient httpclient = null;
        String content = "";
        if (headers == null) {
            headers = new HashMap<>();
        }
        try {
            httpclient = createHttpClientWithNoSsl();
            URIBuilder uriBuilder = new URIBuilder(url);
            if (null != params) {
                for (Map.Entry<String, String> entry : params.entrySet()) {
                    uriBuilder.setParameter(entry.getKey(), entry.getValue());
                }
            }
            HttpGet httpGet = new HttpGet(uriBuilder.build());
            for (Map.Entry<String, String> entry : headers.entrySet()) {
                httpGet.setHeader(entry.getKey(), entry.getValue());
            }

            res = httpclient.execute(httpGet);
            if (res.getCode() == HTTP_OK) {
                InputStream is = res.getEntity().getContent();
                FileUtils.copyInputStreamToFile(is, file);
            }
        } catch (Exception e) {
            log.error("", e);
        } finally {
            if (res != null) {
                log.info(res.getCode()+"");
                try {
                    res.close();
                } catch (IOException e) {
                }
            }
            if (httpclient != null) {
                try {
                    httpclient.close();
                } catch (IOException e) {
                }
            }
        }

    }

    public static String req(String url, Map<String, String> params, Map<String, String> headers) {
        CloseableHttpResponse res = null;
        CloseableHttpClient httpclient = null;
        String content = "";
        if (headers == null) {
            headers = new HashMap<>();
        }
        try {
            httpclient = createHttpClientWithNoSsl();
            URIBuilder uriBuilder = new URIBuilder(url);
            if (null != params) {
                for (Map.Entry<String, String> entry : params.entrySet()) {
                    uriBuilder.setParameter(entry.getKey(), entry.getValue());
                }
            }
            HttpGet httpGet = new HttpGet(uriBuilder.build());
            for (Map.Entry<String, String> entry : headers.entrySet()) {
                httpGet.setHeader(entry.getKey(), entry.getValue());
            }
            res = httpclient.execute(httpGet);

            if (res.getCode() == HTTP_OK) {
                content = EntityUtils.toString(res.getEntity());
            }
        } catch (Exception e) {
            log.error("", e);
        } finally {
            if (res != null) {
                log.info(res.getCode()+"");
                try {
                    res.close();
                } catch (IOException e) {
                }
            }
            if (httpclient != null) {
                try {
                    httpclient.close();
                } catch (IOException e) {
                }
            }
        }
        return content;
    }
}
